# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3

import click
from flask import current_app
from flask import g
# g 是用来存放 request 时的数据的, 这些数据可以被多个函数使用
from flask.cli import with_appcontext


# 使用 g 可以当有相同的 request 调用 get_db 函数可以在第二次调用时, 不必重新
# 建立连接
def get_db():
    """Connect to the application's configured database. The
    connection is unique for each request and will be reused if
    this is called again.
    """
    if "db" not in g:
        # sqlite3.connect 建立与数据库文件之间的连接, 但是这个数据库文件直到
        # 初始化的时候才会创建
        g.db = sqlite3.connect(
            current_app.config['DATABASE'],
            detect_types=sqlite3.PARSE_DECLTYPES
        )
        # 将数据库的每一行返回为一个字典, 这样可以通过 columns 的名称来访问值
        g.db.row_factory = sqlite3.Row

    return g.db


def close_db(e=None):
    """If this request connected to the database, close the
    connection.
    """
    db = g.pop('db', None)

    if db is not None:
        db.close()


def init_db():
    """Clear existing data and create new tables."""
    db = get_db()

    # open_resource 可以 open 一个相对于 flaskr 路径的文件
    with current_app.open_resource('schema.sql') as f:
        db.executescript(f.read().decode('utf8'))


@click.command("init-db")
@with_appcontext
def init_db_command():
    """Clear existing data and create new tables."""
    init_db()
    click.echo("Initialized the database.")


def init_app(app):
    """Register database functions with the Flask app. This is called by
    the application factory.
    """
    app.teardown_appcontext(close_db)
    app.cli.add_command(init_db_command)
